/*
 * Copyright 2011 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.cloudtasks.client;

import java.util.Date;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.SimpleEventBus;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.ServerFailure;

import com.cloudtasks.shared.CloudTasksRequestFactory;
import com.cloudtasks.shared.TaskProxy;
import com.cloudtasks.shared.TaskRequest;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.user.datepicker.client.DatePicker;
import com.google.gwt.user.client.ui.TextBox;

public class CloudTasksWidget extends Composite {
  private static final int STATUS_DELAY = 4000;
  private static final String STATUS_ERROR = "status error";
  private static final String STATUS_NONE = "status none";
  private static final String STATUS_SUCCESS = "status success";

  interface CloudTasksUiBinder extends UiBinder<Widget, CloudTasksWidget> {
  }

  private static CloudTasksUiBinder uiBinder = GWT.create(CloudTasksUiBinder.class);
  
  private static final String BUTTON_STYLE = "send centerbtn";
  
  TaskProxy taskProxy;
  final CloudTasksRequestFactory taskRequestFactory = GWT.create(CloudTasksRequestFactory.class);


  @UiField
  static TextBox calories;

  @UiField
  DivElement status;
  
  @UiField
  Button createButton;
  
  @UiField
  Button queryButton;

  @UiField
  Button deleteButton;
  
  @UiField
  static DateBox datebox;
  
  @UiField 
  static TextBox duration;
  
  /**
   * Timer to clear the UI.
   */
  Timer timer = new Timer() {
    @Override
    public void run() {
      status.setInnerText("");
      status.setClassName(STATUS_NONE);
      calories.setValue("");
      duration.setValue("");
      datebox.setValue(new Date());
    }
  };

  private void setStatus(String message, boolean error) {
    status.setInnerText(message);
    if (error) {
      status.setClassName(STATUS_ERROR);
    } else {
      if (message.length() == 0) {
        status.setClassName(STATUS_NONE);
      } else {
        status.setClassName(STATUS_SUCCESS);
      }
    }

    timer.schedule(STATUS_DELAY);
  }

  public CloudTasksWidget() {
    initWidget(uiBinder.createAndBindUi(this));
    createButton.getElement().setClassName(BUTTON_STYLE);
    queryButton.getElement().setClassName(BUTTON_STYLE);
    deleteButton.getElement().setClassName(BUTTON_STYLE);
    duration.getElement().setClassName("duration");
    calories.getElement().setClassName("duration");

    final EventBus eventBus = new SimpleEventBus();
    final MyRequestFactory requestFactory = GWT.create(MyRequestFactory.class);
    requestFactory.initialize(eventBus);
    taskRequestFactory.initialize(eventBus);
    
	DatePicker datePicker = new DatePicker();
	final Label text = new Label();

	// Set the value in the text box when the user selects a date
	datePicker.addValueChangeHandler(new ValueChangeHandler<Date>() {
		public void onValueChange(ValueChangeEvent<Date> event) {
			Date date = event.getValue();
			@SuppressWarnings("deprecation")
			String dateString = DateTimeFormat.getMediumDateFormat().format(date);
			text.setText(dateString);
		}
	});
	datePicker.setValue(new Date(), true);

	//Create a DateBox
	DateTimeFormat dateFormat = DateTimeFormat.getFormat("MMM,dd yyyy");
	datebox.setFormat(new DateBox.DefaultFormat(dateFormat));
	
	datebox.getElement().setClassName("datebox");
	datebox.getElement().setPropertyString("placeholder", "Add Date");
	duration.getElement().setPropertyString("placeholder", "Duration(min)");
	calories.getElement().setPropertyString("placeholder", "Calories(cal)");
  
    createButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        create();
      }
    });

    deleteButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        delete(taskProxy);
      }
    });

    queryButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        query();
      }
    });
  }

  private void create() {
    TaskRequest request = taskRequestFactory.taskRequest();
    request.createTask().fire(new Receiver<TaskProxy>() {
      @Override
      public void onSuccess(TaskProxy task) {
        taskProxy = task;
        update(taskProxy);
      }
    });
  }

  private void update(TaskProxy task) {
    TaskRequest request = taskRequestFactory.taskRequest();
    taskProxy = request.edit(taskProxy);
    taskProxy.setName(getTaskName());
    taskProxy.setDueDate(getTaskDate());
    taskProxy.setDuration(getDuration());
    request.updateTask(task).fire(new Receiver<TaskProxy>() {
      @Override
      public void onSuccess(TaskProxy task) {
        setStatus("CREATE SUCCESS:(" + task.getId() + "): " + task.getName() + ", " + task.getDuration(), false);
      }
    });
  }

  private void delete(TaskProxy taskProxy) {
	  taskRequestFactory.taskRequest().deleteTask(taskProxy).fire(
			  new Receiver<Void>() {
				  @Override
				  public void onFailure(ServerFailure error) {
					  setStatus(error.getMessage(), true);
				  }          
				  @Override
				  public void onSuccess(Void v) {
					  setStatus("DELETE SUCCESS", false);
				  }
			  });
  }

  private void query() {
    taskRequestFactory.taskRequest().queryTasks().fire(
        new Receiver<List<TaskProxy>>() {
          @Override
          public void onSuccess(List<TaskProxy> taskList) {
            String names = "\n";
            for (TaskProxy task : taskList) {
              names += " (" + task.getId() + "): " + task.getName() + ", " + task.getDuration() + "\n";
            }
            Window.alert("QUERY SUCCESS: Count[" + taskList.size()
                + "] Values:" + names);
          }
        });
  }

  static String getTaskName() {
	String taskName = calories.getValue();
    return taskName;
  }
  
  static Date getTaskDate() {
	  return datebox.getDatePicker().getValue();
  }
  
  static String getDuration() {
	  String strduration = duration.getValue();
	  return strduration;
  }

}
